package com.it.test;

import com.it.bean.Animal;
import com.it.bean.GoodsInfo;
import com.it.bean.User;
import com.it.bean.Users;
import org.junit.Test;

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ：zyx
 * @date ：Created in 2021-12-06-11:13
 * @description：
 * @modified By：
 * @version: $
 */
public class UsersRef {
	@Test
	public void testConstr(){
		// 通过类名.class获取class  方法一
	Class users = 	Users.class;
		System.out.println(users.getName());
		System.out.println(users.getSimpleName());
		System.out.println(users.getPackage());
		//生成该类的对象
		try {
			Class users11 =	Class.forName("com.it.bean.User");
			Object users1 = users11.newInstance();
			
			System.out.println(users11.isInterface());
			System.out.println(users11.isEnum());
			System.out.println(users11.isArray());
			System.out.println(users11.isAnnotation());
			System.out.println(users11.isMemberClass());
			User users2 = (User) users1;
			users2.setAge(21);
			users2.setName("admin");
			System.out.println(users2.getAge());
			
			System.out.println(users2.getIdNumber());
			System.out.println(users2.getName());
			System.out.println(users2.getClass().getName());
			//获取对象的方法
			Class<? extends  Users> clz =    Users.class;
			System.out.println(clz.getPackage());
			System.out.println(clz.getName());
			System.out.println("=====================");
			Class<User> userClass = User.class;
			System.out.println("=======getClasses()====// class.getClasses：获取该类下的所有公共类和接口============");
			//   // class.getClasses：获取该类下的所有公共类和接口
			ClassLoader  clz1 =  userClass.getClassLoader();
			
			System.out.println(clz1.getParent());
			
			Class<?>[]  classes = 	 userClass.getClasses();
			
			for (Class class1:classes
				 ) {
				System.out.println(class1.getName());
				
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
		/*//公共的构造方法
	 Constructor cons[]= users.getConstructors();
		System.out.println(cons.length);*/
	}
	@Test
	public void testExtends(){
		Class users = 	User.class;
		System.out.println("=========将该类转换为父类。====================");
		Class<? extends Animal>  anmials =  users.asSubclass(Animal.class);
		System.out.println(anmials.getName());
		// 获取当前类继承的父类的名字
		System.out.println("--------获取当前类继承的父类的名字-------------------");
		
		Class<? super Animal> an =  users.getSuperclass();
		System.out.println(an.getName());
		//// 获取当前类实现的接口。注意：Java中一个类可以实现多个接口，所以这里是数组
		System.out.println("---------获取当前类实现的接口--------------------");
		Class<?>[] clzInters =    users.getInterfaces();
		System.out.println(clzInters.length);
	}
	//获得类中字段相关的方法
	@Test
	public void testClassField() throws NoSuchFieldException {
		
		Class<User> userClass = User.class;
		// getFields：获取所有的公共字段
		System.out.println("======= getFields：获取所有的公共字段===============");
		Field[] fields = userClass.getFields();
		for (Field field : fields) {
			System.out.println(field.getName());
		}
		System.out.println("======= // 根据名称去获取公共字段===========");
		Field idNumber = userClass.getField("idNumber");
		System.out.println("idNumber---->"+idNumber);
		// // 获取全部的字段，包括私有字段
		System.out.println("---------获取全部的字段，包括私有字段-------------------");
		Field[] declaredFields = userClass.getDeclaredFields();
		for (Field declaredField : declaredFields) {
			System.out.println(declaredField.getName());
		}
		System.out.println("========// 根据名称去获取字段====================");
		// 根据名称去获取字段
		Field age = userClass.getDeclaredField("age");
		System.out.println(age.getName());
	}
	@Test
	public void testClassConstructor1() {
		Class<User> userClass = User.class;
		// 获取所有的公共构造方法
		Constructor<?>[] constructors = userClass.getConstructors();
		for (Constructor<?> constructor : constructors) {
			System.out.println("-------输出构造方法参数：=========="+constructor.getName());
			Class<?>[] parameterTypes = constructor.getParameterTypes();
			for (Class parameter : parameterTypes) {
				System.out.print(parameter.getName() + ",");
			}
			System.out.println("-------构造方法参数输出完毕==========");
		}
		
	}
	
	@Test
	public void testClassConstructor2() throws Exception {
		Class<User> userClass = User.class;
		// 根据参数类型获取公共构造方法，参数就是类型的class
		// ...表示不定长参数，不定长参数可以传多个，也可以不传递。
		Constructor<User> constructor = userClass.getConstructor(String.class, Integer.class, String.class);
		Class<?>[] parameterTypes = constructor.getParameterTypes();
		for (Class<?> parameterType : parameterTypes) {
			System.out.println(parameterType.getName());
		}
	}
	@Test
	public void testClassConstructor3() {
		Class<User> userClass = User.class;
		// 获取所有的构造方法（包括私有构造方法）
		Constructor<?>[] constructors = userClass.getDeclaredConstructors();
		for (Constructor<?> constructor : constructors) {
			System.out.println("输出构造方法参数：");
			Class<?>[] parameterTypes = constructor.getParameterTypes();
			for (Class parameter : parameterTypes) {
				System.out.print(parameter.getName() + ",");
			}
			System.out.println("构造方法参数输出完毕");
		}
	}
	@Test
	public void testClassMethod2() throws NoSuchMethodException {
//获取所有方法
		System.out.println("--------getMethods()--------------");
		Class<User> userClass =    User.class;
		//Method methods[] =  userClass.getMethods();
		Method methods[] =  userClass.getDeclaredMethods();
		
		for (Method method: methods
		) {
			System.out.println(method.getName());
			
		}
		System.out.println("----Method methods[] =  userClass.getMethods();------------------");
		System.out.println("===========根据方法名获取该方法=============");
		Method method =  userClass.getMethod("getIdNumber");
		System.out.println(method.getName());
		Method method2 =  userClass.getMethod("setAge",Integer.class);
		System.out.println(method2.getName());
	}
	
	/**
	 *
	 * @throws Exception
	 */
	@Test
	public void testFieldGet() throws Exception {
		User user1 = new User("木南", 24, "123456");
		Class<User> userClass = User.class;
		Field name =  userClass.getDeclaredField("name");
		System.out.println("name-->"+name);
		System.out.println(name.getName());
		System.out.println(name.getType());
		System.out.println(name.getModifiers());
		System.out.println(Modifier.PRIVATE);
		System.out.println(Modifier.PUBLIC);
		System.out.println(Modifier.STATIC);
		System.out.println(Modifier.ABSTRACT);
		System.out.println(Modifier.FINAL);
		// setAccessible：忽略访问权限修饰符，暴力反射。
		name.setAccessible(true);
		// get方法：获取到当前对象当前字段的值。注意：参数一定要传当前对象
		System.out.println(name.getName()+","+name.get(user1));
		name.set(user1,"张三");
		System.out.println(name.getName()+","+name.get(user1));
		
		
	}
	@Test
	public void testInvokeGetMethod() throws Exception {
		User user = new User("张三", 23, "654321");
		Class<? extends User> userClass = user.getClass();
		Method method = userClass.getDeclaredMethod("getIdNumber");
		System.out.println(method.getName());
		System.out.println(method.getModifiers());
	  /*
	  obj  当前运行的对象
	  Object... args 该方法是否需要传入实际参数
	   public Object invoke(Object obj, Object... args)
	   
	   */
	  Object id = 	method.invoke(user);
		System.out.println(id);
	}
	@Test
	public void testInvokeSetMethod() throws Exception {
		User user = new User("张三", 23, "654321");
		Class<? extends User> userClass = user.getClass();
		// public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
		Method method = userClass.getDeclaredMethod("setIdNumber",String.class);
		System.out.println(method.getName());
		System.out.println(method.getModifiers());
	  /*
	  obj  当前运行的对象
	  Object... args 该方法是否需要传入实际参数
	   public Object invoke(Object obj, Object... args)
	   
	   */
	 method.invoke(user,"8888");
		
		System.out.println(user.getIdNumber());
	}
	@Test
	public void testMethodName() {
		Class<User> userClass = User.class;
		Method[] declaredMethods = userClass.getDeclaredMethods();
		for (Method declaredMethod : declaredMethods) {
			System.out.println(declaredMethod.getModifiers()+" "+declaredMethod.getName());
		}
	}
	@Test
	public void testInvokeSetMethod2() throws Exception {
		User user = new User("张三", 23, "123456");
		System.out.println("反射前：" + user);
		Class<? extends User> userClass = user.getClass();
		Method method = userClass.getDeclaredMethod("setIdNumber", String.class);
		method.setAccessible(true);
		// 执行指定的方法。第一个参数是要执行的哪个对象。后面的参数全部是方法参数
		Object result = method.invoke(user, "666888");
		System.out.println(result);
		System.out.println("反射后：" + user);
	}
	@Test
	public void testNewInstance() throws Exception {
		Class<User> userClass = User.class;
		// Class的newInstance方法默认只走无参构造，不够强大。
		System.out.println("======Class的newInstance方法默认只走无参构造，不够强大。==================");
		User user = userClass.newInstance();
		System.out.println(user);
		System.out.println("==========================");
		Constructor<User> constructor = userClass.getConstructor();
		User user1 = constructor.newInstance();
		System.out.println(user1);
	}
	/**
	 * 通过反射实现把一个对象转换为JSONObject
	 * {user_id:12,user_age:23.....}
	 * 属性名如何获取？   getXxxx
	 * 属性的值如何获取？  getXxxx
	 */
	@Test
	public void user2Json(){
		GoodsInfo goodsInfo = new GoodsInfo("zx001","牛肉","70");
		Users user = new Users(1,"admin",78.0,21);
		//Class<? extends  Users> userClass = user.getClass();
		Class<? extends  GoodsInfo> userClass = goodsInfo.getClass();
		
		Method method[] = userClass.getMethods();
		StringBuffer buffer = new StringBuffer();
		buffer.append("{");
		int i = 0;
		for (Method method1:method
			 ) {
			if(method1.getName().startsWith("get")&& method1.getModifiers()==Modifier.PUBLIC){
				if(i!=0){
					buffer.append(",");
				}
				String filedName = method1.getName().substring(3).toLowerCase();
				System.out.println("filedName-->"+filedName);
				buffer.append("'"+filedName+"'");
				buffer.append(":");
				try {
					//goodsInfo
					//buffer.append(method1.invoke(user));
					buffer.append(method1.invoke(goodsInfo));
					
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
				
				i++;
			}
			
		}
		buffer.append("}");
		System.out.println(buffer.toString());
	}
	
	

	public String obj2Json(Object obj){
		Class<? extends  Object> userClass = obj.getClass();
		
		Method method[] = userClass.getMethods();
		StringBuffer buffer = new StringBuffer();
		buffer.append("{");
		int i = 0;
		for (Method method1:method
		) {
			if(method1.getName().startsWith("get")&& method1.getModifiers()==Modifier.PUBLIC){
				if(i!=0){
					buffer.append(",");
				}
				String filedName = method1.getName().substring(3).toLowerCase();
				System.out.println("filedName-->"+filedName);
				buffer.append("'"+filedName+"'");
				buffer.append(":");
				try {
					//goodsInfo
					//buffer.append(method1.invoke(user));
					buffer.append(method1.invoke(obj));
					
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
				
				i++;
			}
			
		}
		buffer.append("}");
		System.out.println(buffer.toString());
		return buffer.toString();
	}
	//通过反射实现把一个List集合对象转换为JSONArray
	/**
	 * GoodsInfo goodsInfo = new GoodsInfo("zx001","牛肉","70");
	 * 		Users user = new Users(1,"admin",78.0,21);
	 * 	[{},{},{},{}....]
	 */
	
	public void list2JSonArray(List list){
		StringBuffer buffer = new StringBuffer();
		buffer.append("[");
		for (int i = 0; i <list.size() ; i++) {
			 if(i!=0){
			 	buffer.append(",");
			 }
			buffer.append(obj2Json(list.get(i)));
		}
		buffer.append("]");
		System.out.println(buffer.toString());
		
		
		
	}
	@Test
	public void list2JSonArrayTest(){
		GoodsInfo goodsInfo = new GoodsInfo("zx001","牛肉","70");
		Users user = new Users(1,"admin",78.0,21);
		
		List list = new ArrayList();
		list.add(goodsInfo);
		list.add(user);
		
		list2JSonArray(list);
	}
	@Test
	public void testList() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
		System.out.println("=============list添加元素================");
		
		List<User> users = new ArrayList<>();
		users.add(new User("admin1",21,"sx001"));
		users.add(new User("admin2",22,"sx002"));
		users.add(new User("admin3",23,"sx003"));
		System.out.println(users);
		System.out.println("==============验证运行中泛型会被擦除================");
		Class<? extends  List> listClass  =  users.getClass();
		Method metod =   listClass.getDeclaredMethod("add",Object.class);
		metod.invoke(users,"admin5");
		metod.invoke(users,123);
		metod.invoke(users,true);
		metod.invoke(users,1.5f);
		System.out.println(users);
		
	}
}


